package jimm;

import java.util.*;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Font;
import javax.microedition.rms.RecordStore;
import jimm.util.ResourceBundle;
import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

import DrawControls.ListItem;
import DrawControls.VirtualList;
import DrawControls.TextList;
import DrawControls.VirtualListCommands;

import jimm.comm.Icq;
import jimm.comm.SearchAction;
import jimm.comm.Action;


import jimm.comm.Util;
import jimm.Search;
//#sijapp cond.if target="SIEMENS2" | target="MOTOROLA" | target="MIDP2"#
import javax.microedition.io.Connector;
//#sijapp cond.if target is "SIEMENS2"#
import com.siemens.mp.io.file.FileConnection;
import com.siemens.mp.io.file.FileSystemRegistry;
//#sijapp cond.else#
import javax.microedition.io.file.FileConnection;
import javax.microedition.io.file.FileSystemRegistry;
//#sijapp cond.end#
import jimm.ContactListContactItem;
//#sijapp cond.end#
// Class to cache one line in messages list
// All fields are public to easy and fast access




// Visual messages history list
class AllSeeingEyeList extends VirtualList
                         implements VirtualListCommands
		//#sijapp cond.if target="SIEMENS2" | target="MOTOROLA" | target="MIDP2"#
		, Runnable, FileBrowserListener
		//#sijapp cond.end#
{

	static TextList messText;
	
	private final static int SELECTOR_DEL_HISTORY = 2;
	
	// list UIN
	private static String currUin  = new String(),
	                      currName = new String();
	
	// Controls for finding text
	private static Form frmFind;
	private static Command cmdFindOk;
	private static Command cmdFindCancel;
	private static TextField tfldFind;
	private static ChoiceGroup chsFind;

	public static Displayable backScreen;

	
	// Constructor
	public AllSeeingEyeList()
	{
		super(null);
		
		leftCaption = ResourceBundle.getString("options_str");
		rightCaption = ResourceBundle.getString("back");

		setVLCommands(this);
		JimmUI.setColorScheme(this);
		setFullScreenMode(true);
		
	}
	
	// VirtualList command impl.
	public void onCursorMove(VirtualList sender)
	{
	}
	
	// VirtualList command impl.
	public boolean onKeyPress(VirtualList sender, int keyCode, int type)
	{
		if (type != VirtualList.KEY_PRESSED && type != VirtualList.KEY_REPEATED)
			return false;

		if (sender == messText)
		{
			if ((keyCode == Jimm.rightSoftKey) || ((Jimm.is_phone_SE()) && (keyCode == -11)) )
			{
				if (messText.returnable != null)
				{
					Jimm.display.setCurrent(messText.returnable);

					messText = null;
					System.gc();
				}
				return true;

			}

			switch ( getGameAction(keyCode) )
			{
			case Canvas.LEFT: moveInList(-1); return true; 
			case Canvas.RIGHT: moveInList(1); return true;
			}
		}

			if (keyCode == Jimm.leftSoftKey) 
			{
				Jimm.pum.showPopupInEye(this);
				return true;
			}
			else if ((keyCode == Jimm.rightSoftKey) || ((Jimm.is_phone_SE()) && (keyCode == -11)) )
			{
				//processCommand(CMD_BACK, null);
				Jimm.display.setCurrent(backScreen);
				return true;
			}

            return JimmUI.execHotKey(null, keyCode, type);
	}

	// Moves on next/previous message in list and shows message text
	private void moveInList(int offset)
	{
		moveCursor(offset, false);
		showMessText();
	}
	
	// VirtualList command impl.
	public void onItemSelected(VirtualList sender)
	{
		if (sender == this)
		{
			showMessText();
		}
	}
	
	//#sijapp cond.if target="MOTOROLA"|target="MIDP2"|target="SIEMENS2"#
	private boolean cp1251;

	private String exportUin;

	private String directory;

	//additional code -  nedeed beacause of interface FileBrowser
	public ContactListContactItem getCItem()
	{
		return null;
	}

	public void export(String uin)
	{
		exportUin = uin;
		try
		{
			FileBrowser.setListener(this);
			FileBrowser.setParameters(true);
			FileBrowser.activate();
		}
		catch (JimmException e)
		{
			JimmException.handleException(e);
		}
	}

	public void onFileSelect(String s0)
	{
	}

	public void onDirectorySelect(String dir)
	{
		directory = dir;
		(new Thread(this)).start();
	}

	public void run()
	{
	}

	static public final int CMD_DO_COPY	= 1;
	static public final int CMD_INFO	= 2;
	static public final int CMD_SELECT	= 3;
	static public final int CMD_CLEAR	= 4;
	static public final int CMD_CANCEL	= 5;
	static public final int CMD_BACK	= 6;


	public void processCommand(int cmd, Displayable backscr)
	{
		switch (cmd)
		{/*
		case CMD_BACK:
		case CMD_CANCEL:
		{
			Jimm.display.setCurrent(this);
			break;

		}*/
		case CMD_SELECT:
		{
			showMessText();
			break;
		}
		case CMD_CLEAR:
		{
       			AllSeeingEye.clear_all(null);
			messText = null;
			System.gc();

			Jimm.display.setCurrent(backScreen);
			break;
		}
		case CMD_DO_COPY:
		{
			int index = getCurrIndex();
			if (index == -1) return;
			CachedRecord record = AllSeeingEye.getCachedRecord(currUin, index);
			if (record == null) return;
			JimmUI.setClipBoardText
			(
				(record.type == 0),
				"", //record.date,
				record.from,
				record.text
			);

			Jimm.display.setCurrent(this);
			break;
		}
		case CMD_INFO:
		{
			Action act = null;

			CachedRecord record = AllSeeingEye.getCachedRecord(currUin, getCurrIndex());

			Search search = new Search(true, true);
			String data[] = new String[Search.LAST_INDEX];
			data[Search.UIN] = record.from;
			act = new SearchAction(search, data, SearchAction.CALLED_BY_SEARCHUSER);

			try
			{
				Icq.requestAction(act);
			}
			catch (JimmException e)
			{
				JimmException.handleException(e);
				if (e.isCritical()) return;
			}
			// Start timer
			SplashCanvas.addTimerTask("wait", act, true);
			break;

		}
		}
		
	}

	// Show text message of current message of messages list
	public void showMessText()
	{
		if (this.getCurrIndex() >= this.getSize()) return;
		if (messText == null)
		{
			messText = new TextList(null);
			messText.setCursorMode(TextList.SEL_NONE);

			messText.setVLCommands(this);
			JimmUI.setColorScheme(messText);
		}
		
		CachedRecord record = AllSeeingEye.getRecord(currUin, this.getCurrIndex()); 

		messText.clear();
		messText.addBigText(record.text, messText.getTextColor(), Font.STYLE_PLAIN, -1);
		
		messText.doCRLF(-1);
		messText.setCaption(record.from);

		messText.returnable = AllSeeingEye.getList();
	
		Jimm.display.setCurrent(messText);
		messText.repaint();
	}
	
	// returns UIN of list
	static String getCurrUin()
	{
		return currUin;
	}
	
	// sets UIN for list
	static void setCurrUin(String currUin_, String currName_)
	{
		currUin  = currUin_;
		currName = currName_;
	}
	
	// returns size of messages history list
	protected int getSize()
	{
		return AllSeeingEye.getRecordCount(currUin);
	}
	  
	// returns messages history list item data
	protected void get(int index, ListItem item)
	{
		CachedRecord record = AllSeeingEye.getCachedRecord(currUin, index);

		if (record == null) return;
		item.text = record.shortText;
		item.color = (index % 2 == 0) ? getTextColor() : Options.getSchemeColor(Options.CLRSCHHEME_BLUE);
	}
}

// History storage implementation
public class AllSeeingEye
{
	//===================================//
	//                                   //
	//    Data storage implementation    //
	//                                   //
	//===================================//
	
	static final public int CLEAR_EACH_DAY   = 0;
	static final public int CLEAR_EACH_WEEK  = 1;
	static final public int CLEAR_EACH_MONTH = 2;
	
	static final private int VERSION = 1;
	
	static final private String prefix = "hist";
	
	private static RecordStore recordStore;
	private static AllSeeingEyeList list;
	private static String currCacheUin = new String();
	private static Hashtable cachedRecords;
	
	
	final static private int TEXT_START_INDEX = 0;

	public static AllSeeingEyeList getList()
	{
		return list;
	}

/*
	public static void activate(int backplace)
	{
		backScreen = Jimm.display.getCurrent();
		list.showMessText();
	}
*/
	public static void processListCommand(int cmd, Displayable d)
	{
		list.processCommand(cmd, d);
	}
	
	public AllSeeingEye()
	{
	}
	

	// Add message text to contact history
	static synchronized public void addText
	(
		String uin,  // uin sended text  
		byte type,   // type of message 0 - x-status, 1 - status - 2 - added
		long time    // date of message
	)
	{
		if (!Options.getBoolean(Options.OPTION_ALLSEEINGEYE))    // if not enabled
		{
			return;
		}


		if ((!Options.getBoolean(Options.OPTION_EYEMYCONTACTS))&&(ContactList.findUIN(uin)))  // if my contact
		{
			return;  		//  do nothing
		}

		byte[] buffer, textData;
		int textLen;
		boolean lastLine = false;
		
		RecordStore recordStore = null;
		
		if (list != null)
		{
			if (list.getSize() == 0) lastLine = true;
			else if (list.getCurrIndex() == (list.getSize()-1)) lastLine = true;
		}
		
		try
		{
			recordStore = RecordStore.openRecordStore(getRSName(), true); 
			
			ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
			DataOutputStream das = new DataOutputStream(baos);
	
			int[] loclaDate = Util.createDate(time);
			
			das.writeByte(type);
			das.writeUTF(uin);
			das.writeByte(loclaDate[Util.TIME_DAY]);
			das.writeByte(loclaDate[Util.TIME_MON]);
			das.writeShort(loclaDate[Util.TIME_YEAR]);
			das.writeByte(loclaDate[Util.TIME_HOUR]);
			das.writeByte(loclaDate[Util.TIME_MINUTE]);

			textData = baos.toByteArray();
			textLen = textData.length;
			
			recordStore.addRecord(textData, 0, textLen);
			
			recordStore.closeRecordStore();
			recordStore = null;

			loclaDate = null;
			buffer = null;
			textData = null;
		}
		catch (Exception e) 
		{
		}
		
		if (list != null)
		{
			list.repaint();
			if (lastLine) list.setCurrentItem(list.getSize() - 1);
		}
	}
	
	// Returns reference for record store
	static RecordStore getRS()
	{
		return recordStore;
	}
	
	// Returns record store name for UIN
	static private String getRSName()
	{
		return "eye" + Options.getString(Options.OPTION_UIN);
	}
	
	static private void openUINRecords(String uin)
	{
		try
		{
			if (recordStore != null)
			{
				recordStore.closeRecordStore();
				recordStore = null;
				System.gc();
			}
			recordStore = RecordStore.openRecordStore(getRSName(), true);
		}
		catch (Exception e)
		{
			recordStore = null;
			return;
		}
		currCacheUin = uin;
		
		if (cachedRecords == null) cachedRecords = new Hashtable();
	}
	
	// Returns record count for UIN
	static public int getRecordCount(String uin)
	{
//		openUINRecords(uin);
		int result;
		try
		{
			result = recordStore.getNumRecords();
		}
		catch (Exception e)
		{
			result = 0;			
		}
		
		return result; 
	}
	
	// Returns full data of stored message
	static synchronized public CachedRecord getRecord(String uin, int recNo)
	{
		byte[] data;
		CachedRecord result = new CachedRecord();
		
		try
		{
			data = recordStore.getRecord(recNo+1);
			ByteArrayInputStream bais = new ByteArrayInputStream(data, 0, data.length);
			DataInputStream dis = new DataInputStream(bais);


			result.type = dis.readByte();
			result.from = dis.readUTF();
			int dday = dis.readByte();
			int dmon = dis.readByte();
			int dyear = dis.readShort();
			int dhour = dis.readByte();
			int dmin = dis.readByte();


			String reasn;
			String reasnl;

			if (result.type == 0)
			{
				reasn = ResourceBundle.getString("eye_short_xstatus");
				reasnl = ResourceBundle.getString("eye_xstatus");
			}
			else if (result.type == 1)
			{
				reasn = ResourceBundle.getString("eye_short_status");
				reasnl = ResourceBundle.getString("eye_status");
			}			
			else if (result.type == 2)
			{
				reasn = ResourceBundle.getString("eye_short_added");
				reasnl = ResourceBundle.getString("eye_added");
			}
			else if (result.type == 3)
			{
				reasn = ResourceBundle.getString("eye_short_hidden");
				reasnl = ResourceBundle.getString("eye_hidden");
			}
			else
			{
				reasn = reasnl = "unknown";
			}

			ContactListContactItem clci = ContactList.getItembyUIN(result.from);
		
			if (clci != null)
			{
				String clciName = clci.getStringValue(ContactListContactItem.CONTACTITEM_NAME);
				result.text = result.from + " (" + clciName + ")";
				result.shortText = clciName;
				clciName = null;
			}
			else
			{	
				result.text = result.from;
			        result.shortText = result.from;
			}

		


			result.text = result.text + ":\n" + Util.makeTwo(dday)+"."+Util.makeTwo(dmon) + "." + String.valueOf(dyear) + " " +
				Util.makeTwo(dhour)+":"+Util.makeTwo(dmin)+  ",\n" + reasnl;


			result.shortText = result.shortText + " : " + Util.makeTwo(dday)+"."+Util.makeTwo(dmon)+"."+ Util.makeTwo(dyear%100) +  ", " + reasn;

			bais = null;
			dis = null;
			data = null;

			System.gc();

		}
		catch (Exception e)
		{
			result.text = result.date = result.from = "error"; 
			//#sijapp cond.if target is "SIEMENS2" | target is "MIDP2"#
			result.contains_url = false;
			//#sijapp cond.end#
			return null;
		}
		
		return result;
	}
	
	// returns cached short text of the message for history list
	static public CachedRecord getCachedRecord(String uin, int recNo)
	{
		int maxLen = 20;
		CachedRecord cachedRec = (CachedRecord)cachedRecords.get(new Integer(recNo)); 
		if (cachedRec != null) return cachedRec;
		
		cachedRec = getRecord(uin, recNo);
		if (cachedRec == null) return null;
		
        cachedRec.shortText = cachedRec.shortText.replace('\n', ' ');
        cachedRec.shortText = cachedRec.shortText.replace('\r', ' ');

		cachedRecords.put(new Integer(recNo), cachedRec);
		
		return cachedRec;
	}
	
	// Shows history list on mobile phone screen
	static public void showHistoryList(String uin, String nick, boolean rememberBack)
	{
		openUINRecords("");

		if (list == null)
		{
			String caption = ResourceBundle.getString("all_seeing_eye");
			list = new AllSeeingEyeList();
			list.setCaption(caption);
		}
		
		AllSeeingEyeList.setCurrUin(uin, nick);

		list.lock();
		
		if (list.getSize() != 0) 
			list.setCurrentItem(list.getSize()-1);

		list.unlock();

//		if (Jimm.display.getCurrent() != Search.SearchForm.screen)
		if (rememberBack)
			list.backScreen = Jimm.display.getCurrent();

		Jimm.display.setCurrent(list);
	}
	
	
	// Clears cache before hiding history list
	static public void clearCache()
	{
		if (cachedRecords != null)
		{
			cachedRecords.clear();
			cachedRecords = null;
		}
		
		//list = null;
		System.gc();
		
		currCacheUin = new String();
	}
	
	// Sets color scheme for history UI controls
	static public void setColorScheme()
	{
		if (list != null)
		{
			JimmUI.setColorScheme(list);
			if (AllSeeingEyeList.messText != null) 
				JimmUI.setColorScheme(AllSeeingEyeList.messText);
		}
	}

	// Clears all records for all uins
	static synchronized void clear_all(String except)
	{
		try
		{
			recordStore.closeRecordStore();
			recordStore = null;
			RecordStore.deleteRecordStore(getRSName());
			
			System.gc();
		}
		catch (Exception e)
		{
		}
	}
}

